package com.zwcl.common.component.thread.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.zwcl.common.core.exception.BaseException;
import com.zwcl.common.core.utils.http.HttpClientUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * php请求抽象类
 */
@Slf4j
public abstract class AbstractHttpHandle<Param, T> extends AbstractHandle<Param, AbstractHttpHandle.Response<T>> {

    // header的size
    private static final int headerCapacity = 1;


    @Override
    public abstract String getHandleDesc();

    @Override
    public abstract String getUrl();

    @Override
    public abstract String getMethod();

    // 由于这里使用getTypeReference解决泛型嵌套问题，所以这里不使用Class
    @Override
    public Class<Response<T>> getResponseClass() {
        throw new BaseException(
                "该接口不使用getResponseClass方法做反序列化操作，请使用getTypeReference实现反序列化"
        );
    }

    @Override
    public abstract Response<T> checkAndReturn();


    public abstract TypeReference<Response<T>> getTypeReference();


    @Override
    public Map<String, String> buildHeader(Param param) {
        Map<String, String> map = new HashMap<>(headerCapacity);
        map.put("Content-Type", "application/json");
        return map;
    }


    @Override
    public IHandle<Param, Response<T>> request() {
        String handleDesc = this.getHandleDesc();
        Map<String, String> header = this.buildHeader(this.param);
        String param = this.buildJSONBody(super.param);
        String method = this.getMethod();
        String result = HttpClientUtils.postString(
                super.requestUrl, header, param
        );
        log.info("\n接口描述:{}\n请求地址:{}\n方法:{}\n请求头:{}\n请求体:{}\n",
                handleDesc, super.requestUrl,
                method, header, param
        );
        super.response = JSON.parseObject(result, this.getTypeReference());
        return this;
    }


    @Data
    public static class Response<T> {
        private Integer code;
        private String msg;
        private T data;

        public Response<T> check(String handleDesc) {
            if (!code.equals(0)) {
                throw new BaseException(
                        "Http接口【" + handleDesc + "】- 返回结果异常"
                );
            }
            return this;
        }

        public Response<T> check() {
            if (!code.equals(0)) {
                throw new BaseException(msg);
            }
            return this;
        }

        public T getData(){
            return code.equals(0)
                    ? data
                    : null;
        }
    }
}
